package chapter6

import "fmt"

type N int

func (n N)toString()string{
	return fmt.Sprintf("%#v",n)
}
//如果方法内部不引用实例，可省略参数名
func (N)sayHello(){
	fmt.Println("hello world")
}
//如果方法的接收者是基础类型那么将会被复制，如果是指针类型将不会被复制
func (n N)printAddress(){
	fmt.Printf("值传递时的地址和值：%p %v\n",&n,n)
}
func (n *N)printPointAddress(){
	fmt.Printf("指针传递时的地址和值：%p %v\n",n,*n)
}

type X struct {
}
func (x *X) test(){
	fmt.Println("HI",x)
}
func Test1()  {
	var a N =25
	fmt.Println(a.toString())
	fmt.Println("------------------")
	a.sayHello()
	fmt.Println("-------------------")
	fmt.Printf("当前地址和值:%p %v\n",&a,a)
	a.printAddress()
	(&a).printPointAddress()
	fmt.Println("---------------------------")
	a.printAddress()//可以使用实例值或指针调用方法，编译器会自动根据接收类型进行类型转换
	a.printPointAddress()
	//不能用多级指针调用方法
	fmt.Println("-------------------")
	/*p:=&a
	p2:=&p
	p2.printAddress()//会报错
	p2.sayHello()//会报错*/
	//指针类型的接收者必须是合法指针包括nil，或能获取实例的地址
	var b *X
	b.test()//相当于test(nil)
	//X{}.test()//会报错，无法拿取X的准确地址
	//将方法看作普通函数，就很容易理解receiver的传参方式
}